﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls.Ribbon;
using SHomeWorkshop.LunarConcept.Controls;
using System.Xml;
using SHomeWorkshop.LunarConcept.Tools;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows;
using SHomeWorkshop.LunarConcept.Widgets.Interfaces;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年1月18日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：将部件向下移动1个单位。
    /// </summary>
    public static class WidgetMoveToBottomCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [静态][构造方法]
        /// 
        /// ——此方法会初始化并向WPF系统注册一个RoutedUICommand。
        /// </summary>
        static WidgetMoveToBottomCommand()//类型构造器
        {
            routedUICmd = new RoutedUICommand(
                "WidgetMoveToBottomCommand",
                "WidgetMoveToBottomCommand",
                typeof(WidgetMoveToBottomCommand),//创建RoutedUICommand对象
                null);

            routedUICmd.InputGestures.Add(new KeyGesture(Key.Down, ModifierKeys.None, "Down"));

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 判断命令是否可以执行。
        /// ——由于可以直接调用Execute()方法，因此，即使被禁用，也不是不能执行相关功能！！！
        /// </summary>
        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //e.CanExecute = CanExecute();
            e.CanExecute = true;
            return;
        }

        //private static bool CanExecute()
        //{
        //    if (Globals.MainWindow == null) return false;

        //    EditorManager manager = Globals.MainWindow.EditorManager;
        //    if (manager == null) return false;

        //    PageEditor pe = manager.GetMainSelectedPageEditor();
        //    if (pe == null) return false;

        //    List<Widgets.Widget> selectedWidgets = pe.GetSelectedWidgetsList(true);
        //    if (selectedWidgets.Count <= 0) return false;

        //    return true;
        //}

        /// <summary>
        /// 命令被触发时，会调用本事件处理器方法。
        /// ——本方法实际上是调用ExeCute()这个静态方法来实现特定功能。
        /// </summary>
        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute()
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";

            EditorManager manager = Globals.MainWindow.EditorManager;
            if (manager == null) return "　　未找到页面管理器。";

            PageEditor pe = manager.GetMainSelectedPageEditor();
            if (pe == null) return "　　未找到活动页面。";

            List<Widgets.Widget> selectedWidgets = pe.GetSelectedWidgetsList();
            if (selectedWidgets.Count <= 0) return "　　未选定部件。";

            //可能需要刷新自动编号。
            Tools.WidgetCenterYCompareClass sorter = null;
            List<Widgets.TextArea> allTextAreasBeforeMove = null;

            bool autoNumber = false;
            foreach (Widgets.Widget w in selectedWidgets)
            {
                if (w is Widgets.TextArea && w.TitleLevel != Enums.TitleStyle.Normal)
                {
                    autoNumber = true;
                    break;
                }
            }

            //有作为标题的文本块才有可能存在必要刷新自动编号。
            if (autoNumber)
            {
                sorter = new Tools.WidgetCenterYCompareClass();
                allTextAreasBeforeMove = pe.GetAllTextAreaWidgets();
                allTextAreasBeforeMove.Sort(sorter);
            }

            ModifingInfo info = new ModifingInfo() { ModifingDescription = "部件向下移动" };
            manager.GetSelectedPageEditorStatus(info);
            manager.GetSelectedWidgetStatus_Old(info);
            manager.GetSelectedWidgetStatus_New(info);

            ModifingItem<Action, ModifingInfo> mi = new ModifingItem<Action, ModifingInfo>(info);

            List<ILinkableLine> linkedLines = pe.GetLinkedLines(selectedWidgets);

            int lockedWidgetsCount = 0;

            foreach (Widgets.Widget w in selectedWidgets)
            {
                if (w.IsLocked)
                {
                    w.RefreshLocation();
                    lockedWidgetsCount++;
                    continue;
                }

                Widgets.ContentWidget cw = w as Widgets.ContentWidget;
                if (cw != null)
                {
                    Point newLocation = new Point(cw.Location.X, cw.Location.Y + 1);
                    Action actMove = new Action(cw.MasterEditor.Id, cw.Id, cw.GetType().Name,
                        XmlTags.LocationTag, cw.Location.ToString(), newLocation.ToString());
                    cw.Location = newLocation;
                    mi.AddAction(actMove);
                    continue;
                }

                Widgets.LineWidget lw = w as Widgets.LineWidget;
                if (lw != null)
                {
                    Widgets.Interfaces.ILinkableLine linkedLine = lw as Widgets.Interfaces.ILinkableLine;
                    if (linkedLine != null && linkedLine.IsLinked)
                    {
                        continue;
                    }

                    lw.MoveDown(mi);
                    continue;
                }
            }

            //刷新相关的关系线
            pe.RefreshLinkedLines(mi, linkedLines);

            manager.RegisterModifingItem(mi);

            //可能需要刷新自动编号。
            if (autoNumber && sorter != null && allTextAreasBeforeMove != null)
            {
                List<Widgets.TextArea> allTextAreasAfterMove = pe.GetAllTextAreaWidgets();
                allTextAreasAfterMove.Sort(sorter);

                if (allTextAreasBeforeMove.Count == allTextAreasAfterMove.Count)
                {

                    bool needRefresh = false;

                    for (int i = 0; i < allTextAreasAfterMove.Count - 1; i++)
                    {
                        if (allTextAreasAfterMove[i] != allTextAreasBeforeMove[i])
                        {
                            needRefresh = true; //部件顶边的移动造成了编号变化。
                            break;
                        }
                    }

                    if (needRefresh)
                    {
                        manager.RefreshAutoNumberStrings();
                        mi.NeedRefreshAutoNumberStrings = true;
                    }
                }
            }
            if (lockedWidgetsCount > 0)
            {
                MessageBox.Show("　　有【 " + lockedWidgetsCount.ToString() + " 】个部件处于被锁定状态，不可移动。已复位。",
                    Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            }

            return string.Empty;
        }

        #endregion
    }
}
